package pl.edu.agh.gronoMining.resultAnalyzer.resultNormalizer.parser;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.ParseException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleGraph;

import pl.edu.agh.gronoMining.resultAnalyzer.resultNormalizer.graph.Edge;
import pl.edu.agh.gronoMining.resultAnalyzer.resultNormalizer.graph.Vertex;


public class LineParser implements GraphParser {

	
	@Override
	public Graph<Vertex, Edge>[] parse(File graphFile) throws ParseException {
		Set<Graph<Vertex, Edge>> graphsSet = new HashSet<Graph<Vertex, Edge>>();
		try {
			BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(graphFile)));
			String line;

			Graph<Vertex, Edge> currentGraph = null;
			Map<Integer, Vertex> currentGraphVertexMap = new HashMap<Integer, Vertex>();
			
			int lineNo = 1;
			while ((line = reader.readLine()) != null) {
				String[] lineElements = line.trim().split(" ");
				
				if ("t".equals(lineElements[0])) {
					
					if (currentGraph != null)
						graphsSet.add(currentGraph);
					currentGraph = new SimpleGraph<Vertex, Edge>(Edge.class);
					currentGraphVertexMap = new HashMap<Integer, Vertex>();
					
				} else if ("v".equals(lineElements[0])) {
					
					int id = Integer.parseInt(lineElements[1]);
					int label = Integer.parseInt(lineElements[2]);
					
					Vertex v = new Vertex(id, label);
					
					currentGraph.addVertex(v);
					
					currentGraphVertexMap.put(id, v);
					
				} else if ("e".equals(lineElements[0])) {
					
					int id1 = Integer.parseInt(lineElements[1]);
					int id2 = Integer.parseInt(lineElements[2]);
					int label = Integer.parseInt(lineElements[3]);
					Edge e = new Edge(label);
					currentGraph.addEdge(currentGraphVertexMap.get(id1), currentGraphVertexMap.get(id2), e);
					
				} else if ("=>".equals(lineElements[0])) {
					
				} else if ("".equals(lineElements[0])) {
					
				} else {
					System.out.println(lineNo+": "+lineElements[0]);
					throw new ParseException("unknown identifier",lineNo);
				}
				lineNo++;
			}
			
			if (currentGraph != null)
				graphsSet.add(currentGraph);
			
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Graph[] graphArray = new Graph[graphsSet.size()];
		int i = 0;
		for (Graph g : graphsSet)
			graphArray[i++] = g;
		return graphArray;
	}
	
	public void serializeToFile(Set<Graph<Vertex, Edge>> graphsSet, File outputFile) throws IOException {
		
		PrintWriter writer = new PrintWriter(new FileWriter(outputFile));
		int graphId = 0;
		for (Graph<Vertex, Edge> g : graphsSet) {
			writer.println("t # "+graphId++);
			for (Vertex v : g.vertexSet()) {
				writer.println("v "+v.getId()+" "+v.getLabel());
			}
			for (Edge e : g.edgeSet()) {
				writer.println("e "+g.getEdgeSource(e).getId()+" "+g.getEdgeTarget(e).getId()+" "+e.getLabel());
			}
			writer.println();
		}
		writer.flush();
	}
}
